#include "Register.h"

#include <sstream>
#include <Poco/DOM/Document.h>
#include <Poco/DOM/NodeIterator.h>
#include "misc/Interface.h"
#include "misc/Debug.h"
#include "nameserver/NameServer.h"
/*********************************************************/
void Register::execute()
{
	NameServer& ns = NameServer::Instance();
	Interface& ui = Interface::Instance();
	
	ns.mutex.lock();
	bool found = false;
	for ( unsigned int i = 0; i<ns.rings.size(); i++ ) {
		if ( ns.rings[i].getName() == ringName ) {
			if ( ns.rings[i].getAddr() != ringAddr ) {
				ns.mutex.unlock();
				throw(std::logic_error("Ring information invalid, ringName and address aren't combined correctly"));
			}

			ns.rings[i].addNode(hostAddr);
			ui << hostAddr << " registered on ring: " << ringName << "@" << ringAddr << std::endl;
			ui.flush();
			found = true;
			break;
		}
	}
	
	if ( !found ) {
		Ring		r;
		r.setName(ringName);
		r.setAddr(ringAddr);
		r.addNode(hostAddr);
		ns.rings.push_back(r);

		ui << hostAddr << " registered new ring: " << ringName << "@" << ringAddr << std::endl;
		ui.flush();
	}
	ns.mutex.unlock();

	// Send an ack in reply
	ack();
}
/*********************************************************/
std::string Register::serialize() const
{
	NameServer& ns = NameServer::Instance();
	std::ostringstream		ostr;
	id = ns.getID();

	ostr << "<GS id='" << id << "'>";
	ostr << "<Register>";
	ostr << "<hostaddr>" << hostAddr << "</hostaddr>";
	ostr << "<ringname>" << ringName << "</ringname>";
	ostr << "<ringaddr>" << ringAddr << "</ringaddr>";
	ostr << "</Register>";
	ostr << "</GS>";

	return( ostr.str() );
}
/*********************************************************/
void Register::deserialize(Poco::XML::NodeIterator& it)
{
	Poco::XML::Node* pNode = it.nextNode();
	if (( pNode ) && ( pNode->nodeName() == "hostaddr" )) {
		hostAddr = pNode->innerText();
	} else {
		throw(std::logic_error("Register message didn't carry the host address field or the fields were incorrectly ordered!"));
	}

	pNode = it.nextNode();
	if (( pNode ) && ( pNode->nodeName() == "ringname" )) {
		ringName = pNode->innerText();
	} else {
		throw(std::logic_error("Register message didn't carry the ring name field or the fields were incorrectly ordered!"));
	}

	pNode = it.nextNode();
	if (( pNode ) && ( pNode->nodeName() == "ringaddr" )) {
		ringAddr = pNode->innerText();
	} else {
		throw(std::logic_error("Register message didn't carry the ring address field or the fields were incorrectly ordered!"));
	}
}
/*********************************************************/
